﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Projektarbete
{
    class HUDData
    {
        public string prefix;
        public string suffix;

        public HUDData(string prefix, string suffix)
        {
            this.prefix = prefix;
            this.suffix = suffix;
        }
    }

    class PositionedString
    {
        public string text;
        public Vector2 position;

        public PositionedString(string text, Vector2 position)
        {
            this.text = text;
            this.position = position;
        }
    }

    class Button
    {
        public string text;
        public Vector2 position;

        public Rectangle hitbox;

        private VoidPointer ClickPointer;

        public Button(string text, Vector2 position, VoidPointer ClickPointer, SpriteFont spriteFont)
        {
            this.text = text;
            this.position = position;
            this.ClickPointer = ClickPointer;

            hitbox = new Rectangle((int)position.X, (int)position.Y, (int)spriteFont.MeasureString(text).X, (int)spriteFont.MeasureString(text).Y);
        }

        public Button(string text, Vector2 position, VoidPointer ClickPointer, Rectangle hitbox)
        {
            this.text = text;
            this.position = position;
            this.ClickPointer = ClickPointer;
            this.hitbox = hitbox;
        }

        public void Click()
        {
            ClickPointer();
        }
    }

    class Popup
    {
        public virtual void Update()
        {

        }

        public virtual void Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
        {

        }
    }

    class ChestPopup : Popup
    {
        protected Texture2D background;
        protected SpriteFont spriteFont;

        protected LinkedList<Rectangle> itemHitBoxes;
        protected LinkedList<Rectangle> inventoryItemHitBoxes;
        protected LinkedList<Rectangle> hitBoxes;
        protected LinkedList<Rectangle> inventoryHitBoxes;
        protected LinkedList<PositionedString> positionedString;
        protected LinkedList<Button> buttons;

        protected Vector2 position;

        protected Item[][] contents;
        protected Item[][] inventoryContents;
        protected Item lastSelectedItem;
        protected Item inventoryLastSelectedItem;
        protected Item selectedItem;
        protected Item inventorySelectedItem;

        protected int itemScroll;
        protected int inventoryItemScroll;
        protected int textScroll;
        protected int inventoryTextScroll;
        protected int returnArrayLength;
        protected int inventoryReturnArrayLength;
        protected int compareTextIndex;

        protected string text;
        protected string inventoryText;
        protected string quickInfoText;
        protected string inventoryQuickInfoText;
        protected string[] compareText;

        protected Rectangle itemRectangle;
        protected Rectangle inventoryItemRectangle;
        protected Rectangle quickInfoRectangle;
        protected Rectangle inventoryQuickInfoRectangle;

        protected Texture2D white;

        protected bool locked;
        protected bool inventoryLocked;

        protected VoidPointerIntArg sortInventory;
        protected VoidPointerItemArg dropItem;

        //public VoidPointer UpdateContentsPointer;

        //TODO: Fix emptyTile text popping

        /// <summary>
        /// Creates a new InventoryPopup
        /// </summary>
        /// <param name="spriteFont">The font that should be used</param>
        /// <param name="background">The background image which sould be used</param>
        /// <param name="position">The position of the background image</param>
        public ChestPopup(SpriteFont spriteFont, Texture2D background, Vector2 position, VoidPointerIntArg sortInventory, VoidPointerItemArg dropItem)
        {
            this.position = position;
            this.spriteFont = spriteFont;
            this.background = background;
            this.sortInventory = sortInventory;
            this.dropItem = dropItem;

            selectedItem = new ItemPresets.EmptySlot();
            inventorySelectedItem = new ItemPresets.EmptySlot();

            itemScroll = 0;
            inventoryItemScroll = 0;
            textScroll = 0;
            inventoryTextScroll = 0;
            returnArrayLength = 0;
            inventoryReturnArrayLength = 0;

            locked = false;
            inventoryLocked = false;

            itemRectangle = new Rectangle(80, 80, 280, 320);
            inventoryItemRectangle = new Rectangle(440, 80, 280, 320);
            quickInfoRectangle = new Rectangle(0, 0, 0, 0);
            inventoryQuickInfoRectangle = new Rectangle(0, 0, 0, 0);

            text = string.Empty;
            inventoryText = string.Empty;
            quickInfoText = string.Empty;
            inventoryQuickInfoText = string.Empty;

            positionedString = new LinkedList<PositionedString>();
            buttons = new LinkedList<Button>();

            hitBoxes = new LinkedList<Rectangle>();
            itemHitBoxes = new LinkedList<Rectangle>();
            inventoryItemHitBoxes = new LinkedList<Rectangle>();

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 7; x++)
                {
                    itemHitBoxes.AddLast(new Rectangle(80 + 40 * x, 80 + 40 * y, 40, 40));
                }
            }

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 7; x++)
                {
                    inventoryItemHitBoxes.AddLast(new Rectangle(440 + 40 * x, 80 + 40 * y, 40, 40));
                }
            }

            compareText = new string[] { "nothing", "name", "price", "size", "weight" };

            buttons.AddLast(new Button("Sort after ", new Vector2(70, 550), new VoidPointer(CycleSort), new Rectangle(70, 550, 200, 28)));
            buttons.AddLast(new Button("Drop item", new Vector2(280, 550), new VoidPointer(DropItem), spriteFont));

            white = Global.White;
        }

        private void DropItem()
        {
            if (selectedItem.getTexture != Global.ItemEmpty)
            {
                dropItem(selectedItem);
                selectedItem = new ItemPresets.EmptySlot();
                locked = false;
            }
        }

        //TODO: Selected item persistant. Drop quickly

        private void CycleSort()
        {
            compareTextIndex++;

            if (compareTextIndex > compareText.Length - 1)
                compareTextIndex = 0;

            sortInventory(compareTextIndex);
        }

        public void UpdateContents(Item[][] contents, Item[][] inventoryContents)
        {
            returnArrayLength = contents.GetLength(0);
            inventoryReturnArrayLength = inventoryContents.GetLength(0);

            this.contents = contents;
            this.inventoryContents = inventoryContents;
        }

        /// <summary>
        /// Read input
        /// </summary>
        public override void Update()
        {
            int mouseWheelValue = Input.GetMouseWheelValueNormalized();
            int lastMouseWheelValue = Input.GetLastMouseWheelValueNormalized();

            Point mousePosition = Input.GetMousePosition();

            if (itemRectangle.Contains(mousePosition))
            {
                if (Input.IsKeyDown(Global.KeyConfig[5])) //[5] = modifyer key
                {
                    if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                        textScroll++;
                    else if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                        textScroll--;

                    if (mouseWheelValue != lastMouseWheelValue)
                        textScroll += (mouseWheelValue - lastMouseWheelValue) * 10;
                }
                else
                {
                    if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Up))
                    {
                        itemScroll--;
                        itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                    }
                    else if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Down))
                    {
                        itemScroll++;
                        itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                    }

                    if (mouseWheelValue != lastMouseWheelValue)
                    {
                        itemScroll += lastMouseWheelValue - mouseWheelValue;
                        itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                    }

                    textScroll = (int)MathHelper.Clamp(textScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);
                }

                if (Input.IsNewMouseTwoPress())
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 80) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 6);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item clickedItem = contents[clickPosition.Y + itemScroll][clickPosition.X];

                    if (locked)
                    {
                        locked = false;
                        selectedItem = new ItemPresets.EmptySlot();
                    }
                    else
                        if (clickedItem.getTexture != Global.ItemEmpty)
                        {
                            locked = true;
                            selectedItem = clickedItem;

                            quickInfoRectangle = Rectangle.Empty;
                            quickInfoText = string.Empty;
                        }
                }

                //itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                //textScroll = (int)MathHelper.Clamp(textScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);

                if (!locked)
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 80) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 6);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item item = contents[clickPosition.Y + itemScroll][clickPosition.X];

                    if (item != lastSelectedItem)
                    {
                        switch (item.getType)
                        {
                            case ItemTypes.Empty:
                                text = string.Empty;

                                quickInfoText = string.Empty;
                                quickInfoRectangle = Rectangle.Empty;
                                break;
                            case ItemTypes.HealthPotion:
                                text = "Name: " + item.getName + "\n" +
                                       "Health restored: " + item.getProperty("healthrestored") + "\n" +
                                       "Sell price: " + item.getPrice + "\n" +
                                       "Size: " + item.getSize + "\n" +
                                       "Weight: " + item.getWeight + "\n" +
                                       "Description:\n" + Global.TrimString(Global.BasicFont, 290, item.getDescription);

                                quickInfoText = "Name: " + item.getName + "\n" +
                                        "Health restored: " + item.getProperty("healthrestored") + "\n" +
                                        "Sell price: " + item.getPrice + "\n" +
                                        "Size: " + item.getSize + "\n" +
                                        "Weight: " + item.getWeight + "\n";
                                Point TextSize = new Point((int)spriteFont.MeasureString(quickInfoText).X, (int)spriteFont.MeasureString(quickInfoText).Y);

                                quickInfoRectangle = new Rectangle(mousePosition.X, mousePosition.Y, TextSize.X, TextSize.Y - 24);

                                //if (mousePosition.X + quickInfoRectangle.Width > itemRectangle.Right)
                                //    quickInfoRectangle.X = mousePosition.X - quickInfoRectangle.Width;

                                if (mousePosition.Y + quickInfoRectangle.Height > itemRectangle.Bottom)
                                    quickInfoRectangle.Y = mousePosition.Y - quickInfoRectangle.Height;

                                break;
                            default:
                                quickInfoText = string.Empty;
                                break;
                        }

                        if (!Input.IsKeyDown(Global.KeyConfig[5]))
                            textScroll = 0;
                    }
                    else
                    {
                        quickInfoRectangle.Location = mousePosition;

                        //if (mousePosition.X + quickInfoRectangle.Width > itemRectangle.Right)
                        //    quickInfoRectangle.X = mousePosition.X - quickInfoRectangle.Width;

                        if (mousePosition.Y + quickInfoRectangle.Height > itemRectangle.Bottom)
                            quickInfoRectangle.Y = mousePosition.Y - quickInfoRectangle.Height;

                    }
                    lastSelectedItem = item;
                }
            }
            else if (inventoryItemRectangle.Contains(mousePosition)) //################################################################\\
            {
                if (Input.IsKeyDown(Global.KeyConfig[5])) //[5] = modifyer key
                {
                    if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                        inventoryTextScroll++;
                    else if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                        inventoryTextScroll--;

                    if (mouseWheelValue != lastMouseWheelValue)
                        inventoryTextScroll += (mouseWheelValue - lastMouseWheelValue) * 10;
                }
                else
                {
                    if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Up))
                    {
                        inventoryItemScroll--;
                        inventoryItemScroll = (int)MathHelper.Clamp(inventoryItemScroll, 0, inventoryReturnArrayLength - 8);
                    }
                    else if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Down))
                    {
                        inventoryItemScroll++;
                        inventoryItemScroll = (int)MathHelper.Clamp(inventoryItemScroll, 0, inventoryReturnArrayLength - 8);
                    }
                    
                    if (mouseWheelValue != lastMouseWheelValue)
                    {
                        inventoryItemScroll += lastMouseWheelValue - mouseWheelValue;
                        inventoryItemScroll = (int)MathHelper.Clamp(inventoryItemScroll, 0, inventoryReturnArrayLength - 8);
                    }

                    inventoryTextScroll = (int)MathHelper.Clamp(inventoryTextScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);
                }

                if (Input.IsNewMouseTwoPress())
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 440) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 6);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item inventoryClickedItem = inventoryContents[clickPosition.Y + inventoryItemScroll][clickPosition.X];

                    if (inventoryLocked)
                    {
                        inventoryLocked = false;
                        inventorySelectedItem = new ItemPresets.EmptySlot();
                    }
                    else
                        if (inventoryClickedItem.getTexture != Global.ItemEmpty)
                        {
                            inventoryLocked = true;
                            inventorySelectedItem = inventoryClickedItem;

                            inventoryQuickInfoRectangle = Rectangle.Empty;
                            inventoryQuickInfoText = string.Empty;
                        }
                }

                //itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                //textScroll = (int)MathHelper.Clamp(textScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);

                //Errorhere fix inventory itemtext

                if (!inventoryLocked)
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 440) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 6);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item item = inventoryContents[clickPosition.Y + inventoryItemScroll][clickPosition.X];

                    if (item != inventoryLastSelectedItem)
                    {
                        switch (item.getType)
                        {
                            case ItemTypes.Empty:
                                inventoryText = string.Empty;

                                inventoryQuickInfoText = string.Empty;
                                inventoryQuickInfoRectangle = Rectangle.Empty;
                                break;
                            case ItemTypes.HealthPotion:
                                inventoryText = "Name: " + item.getName + "\n" +
                                       "Health restored: " + item.getProperty("healthrestored") + "\n" +
                                       "Sell price: " + item.getPrice + "\n" +
                                       "Size: " + item.getSize + "\n" +
                                       "Weight: " + item.getWeight + "\n" +
                                       "Description:\n" + Global.TrimString(Global.BasicFont, 290, item.getDescription);

                                inventoryQuickInfoText = "Name: " + item.getName + "\n" +
                                        "Health restored: " + item.getProperty("healthrestored") + "\n" +
                                        "Sell price: " + item.getPrice + "\n" +
                                        "Size: " + item.getSize + "\n" +
                                        "Weight: " + item.getWeight + "\n";
                                Point TextSize = new Point((int)spriteFont.MeasureString(inventoryQuickInfoText).X, (int)spriteFont.MeasureString(inventoryQuickInfoText).Y);

                                inventoryQuickInfoRectangle = new Rectangle(mousePosition.X - TextSize.X, mousePosition.Y, TextSize.X, TextSize.Y - 24);

                                if (mousePosition.Y + inventoryQuickInfoRectangle.Height > itemRectangle.Bottom)
                                    inventoryQuickInfoRectangle.Y = mousePosition.Y - inventoryQuickInfoRectangle.Height;

                                break;
                            default:
                                inventoryQuickInfoText = string.Empty;
                                break;
                        }

                        if (!Input.IsKeyDown(Global.KeyConfig[5]))
                            inventoryTextScroll = 0;
                    }
                    else
                    {
                        //inventoryQuickInfoRectangle.Location = mousePosition;

                        inventoryQuickInfoRectangle.Location = new Point(mousePosition.X - inventoryQuickInfoRectangle.Width, mousePosition.Y);

                        if (mousePosition.Y + inventoryQuickInfoRectangle.Height > itemRectangle.Bottom)
                            inventoryQuickInfoRectangle.Y = mousePosition.Y - inventoryQuickInfoRectangle.Height;

                    }
                    inventoryLastSelectedItem = item;
                }
            }
            else
            {
                if (!locked)
                {
                    quickInfoRectangle = Rectangle.Empty;
                    quickInfoText = string.Empty;

                    lastSelectedItem = new ItemPresets.EmptySlot();
                }

                if (!inventoryLocked)
                {
                    inventoryQuickInfoRectangle = Rectangle.Empty;
                    inventoryQuickInfoText = string.Empty;

                    inventoryLastSelectedItem = new ItemPresets.EmptySlot(); 
                }

                if (Input.IsNewMouseOnePress())
                {
                    foreach (Button button in buttons)
                    {
                        if (button.hitbox.Contains(mousePosition))
                            button.Click();
                    }
                }
            }
        }

        /// <summary>
        /// Draws the entire popup
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="graphicsDevice"></param>
        public override void Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
        {
            Random random = new Random();
            spriteBatch.Draw(background, position, Color.White);

            for (int y = 0; y < 8; y++)
                for (int x = 0; x < 7; x++)
                    spriteBatch.Draw(contents[y + itemScroll][x].getTexture, new Vector2(82 + x * 35 + x * 5, 86 + y * 35 + y * 5), Color.White);

            for (int y = 0; y < 8; y++)
                for (int x = 0; x < 7; x++)
                    spriteBatch.Draw(inventoryContents[y + inventoryItemScroll][x].getTexture, new Vector2(442 + x * 35 + x * 5, 86 + y * 35 + y * 5), Color.White);

            foreach (PositionedString thisPositionedString in positionedString)
                spriteBatch.DrawString(spriteFont, thisPositionedString.text, thisPositionedString.position, Color.White);

            foreach (Button button in buttons)
                spriteBatch.DrawString(spriteFont, button.text, button.position, Color.White);

            //spriteBatch.DrawString(spriteFont, compareText[compareTextIndex], new Vector2(188, 550), Color.White);

            spriteBatch.Draw(white, quickInfoRectangle, new Color(0, 0, 0) * 0.8f);
            spriteBatch.Draw(white, inventoryQuickInfoRectangle, new Color(0, 0, 0) * 0.8f);
            spriteBatch.DrawString(spriteFont, quickInfoText, new Vector2(quickInfoRectangle.X, quickInfoRectangle.Y), Color.White);
            spriteBatch.DrawString(spriteFont, inventoryQuickInfoText, new Vector2(inventoryQuickInfoRectangle.X, inventoryQuickInfoRectangle.Y), Color.White);

            spriteBatch.End();

            //Klipp ut allt som är utanför infoText rutan
            graphicsDevice.RasterizerState = new RasterizerState() { ScissorTestEnable = true };
            graphicsDevice.ScissorRectangle = new Rectangle(65, 445, 670, 90);

            spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, graphicsDevice.RasterizerState);

            spriteBatch.DrawString(spriteFont, text, new Vector2(65, 440 + textScroll), Color.White);
            spriteBatch.DrawString(spriteFont, inventoryText, new Vector2(443, 440 + inventoryTextScroll), Color.White);

            //spritebatch.End();
            //Do not add spriteBatch.end();
        }
    }

    class InventoryPopup : Popup
    {
        protected Texture2D background;
        protected SpriteFont spriteFont;

        protected LinkedList<Rectangle> itemHitBoxes;
        protected LinkedList<Rectangle> hitBoxes;
        protected LinkedList<PositionedString> positionedString;
        protected LinkedList<Button> buttons;

        protected Vector2 position;

        protected Item[][] inventoryContents;
        protected Item lastSelectedItem;
        protected Item selectedItem;

        protected int itemScroll;
        protected int textScroll;
        protected int returnArrayLength;
        protected int compareTextIndex;

        protected string text;
        protected string quickInfoText;
        protected string[] compareText;

        protected Rectangle itemRectangle;
        protected Rectangle quickInfoRectangle;

        protected Texture2D white;

        protected bool locked;

        protected VoidPointerIntArg sortInventory;
        protected VoidPointerItemArg dropItem;

        //public VoidPointer UpdateContentsPointer;

        /// <summary>
        /// Creates a new InventoryPopup
        /// </summary>
        /// <param name="spriteFont">The font that should be used</param>
        /// <param name="background">The background image which sould be used</param>
        /// <param name="position">The position of the background image</param>
        public InventoryPopup(SpriteFont spriteFont, Texture2D background, Vector2 position, VoidPointerIntArg sortInventory, VoidPointerItemArg dropItem)
        {
            this.position = position;
            this.spriteFont = spriteFont;
            this.background = background;
            this.sortInventory = sortInventory;
            this.dropItem = dropItem;

            selectedItem = new ItemPresets.EmptySlot();

            itemScroll = 0;
            textScroll = 0;
            returnArrayLength = 0;

            locked = false;

            itemRectangle = new Rectangle(80, 80, 640, 320);
            quickInfoRectangle = new Rectangle(0, 0, 0, 0);

            text = string.Empty;
            quickInfoText = string.Empty;

            positionedString = new LinkedList<PositionedString>();
            buttons = new LinkedList<Button>();

            hitBoxes = new LinkedList<Rectangle>();
            itemHitBoxes = new LinkedList<Rectangle>();

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 16; x++)
                {
                    itemHitBoxes.AddLast(new Rectangle(80 + 40 * x, 80 + 40 * y, 40, 40));
                }
            }

            compareText = new string[] { "nothing", "name", "price", "size", "weight" };

            buttons.AddLast(new Button("Sort after ", new Vector2(70, 550), new VoidPointer(CycleSort), new Rectangle(70, 550, 200, 28)));
            buttons.AddLast(new Button("Drop item", new Vector2(280, 550), new VoidPointer(DropItem), spriteFont));

            white = Global.White;
        }

        private void DropItem()
        {
            if (selectedItem.getTexture != Global.ItemEmpty)
            {
                dropItem(selectedItem);
                selectedItem = new ItemPresets.EmptySlot();
                locked = false;
            }
        }

        //TODO: Selected item persistant. Drop quickly

        private void CycleSort()
        {
            compareTextIndex++;

            if (compareTextIndex > compareText.Length - 1)
                compareTextIndex = 0;

            sortInventory(compareTextIndex);
        }

        public void UpdateContents(Item[][] contents)
        {
            if (contents.GetLength(0) < returnArrayLength)
                if(itemScroll == returnArrayLength - 8)
                    itemScroll--;

            returnArrayLength = contents.GetLength(0);
            inventoryContents = contents;
            
            /*returnArrayLength = contents.GetLength(0);
            Item[][] returnedContents = contents;

            itemScroll = 0;

            inventoryContents = new Item[8][];

            int maxX = 0;

            for (int x = 0; x < 16; x++)
            {
                if (contents[returnArrayLength - 1][x] == null)
                {
                    maxX = x - 1;
                    break;
                }
            }

            if (returnArrayLength < 8)
            {
                for (int y = 0; y < 8; y++)
                {
                    inventoryContents[y] = new Item[16];

                    for (int x = 0; x < 16; x++)
                    {
                        if (y == returnArrayLength - 1)
                        {
                            if (x > maxX)
                                inventoryContents[y][x] = new ItemPresets.EmptySlot();
                            else
                                inventoryContents[y][x] = returnedContents[y][x];
                        }
                        else if (y > returnArrayLength - 1)
                        {
                            inventoryContents[y][x] = new ItemPresets.EmptySlot();
                        }
                        else
                        {
                            inventoryContents[y][x] = returnedContents[y][x];
                        }
                    }
                }
            }
            else
            {
                inventoryContents = contents;

                for (int x = 0; x < 16; x++)
                {
                    if (inventoryContents[returnArrayLength - 1][x] == null)
                        inventoryContents[returnArrayLength - 1][x] = new ItemPresets.EmptySlot();
                }
            }*/
        }

        /// <summary>
        /// Read input
        /// </summary>
        public override void Update()
        {
            int mouseWheelValue = Input.GetMouseWheelValueNormalized();
            int lastMouseWheelValue = Input.GetLastMouseWheelValueNormalized();

            if (Input.IsKeyDown(Global.KeyConfig[5])) //[5] = modifyer key
            {
                if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                    textScroll++;
                else if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                    textScroll--;

                if (mouseWheelValue != lastMouseWheelValue)
                    textScroll += (mouseWheelValue - lastMouseWheelValue) * 10;
            }
            else
            {
                if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Up))
                {
                    itemScroll--;
                    itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                }
                else if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Down))
                {
                    itemScroll++;
                    itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                }

                if (mouseWheelValue != lastMouseWheelValue)
                {
                    itemScroll += lastMouseWheelValue - mouseWheelValue;
                    itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                }

                textScroll = (int)MathHelper.Clamp(textScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);
            }

            Point mousePosition = Input.GetMousePosition();

            if (itemRectangle.Contains(mousePosition))
            {
                if (Input.IsNewMouseTwoPress())
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 80) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 15);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item clickedItem = inventoryContents[clickPosition.Y + itemScroll][clickPosition.X];

                    if (locked)
                    {
                        locked = false;
                        selectedItem = new ItemPresets.EmptySlot();
                    }
                    else
                        if (clickedItem.getTexture != Global.ItemEmpty)
                        {
                            locked = true;
                            selectedItem = clickedItem;
                        }
                }

                //itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                //textScroll = (int)MathHelper.Clamp(textScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);

                if (!locked)
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 80) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 15);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item item = inventoryContents[clickPosition.Y + itemScroll][clickPosition.X];

                    if (item != lastSelectedItem)
                    {
                        switch (item.getType)
                        {
                            case ItemTypes.Empty:
                                text = "This is an empty slot. Items go here";

                                quickInfoText = string.Empty;
                                quickInfoRectangle = Rectangle.Empty;
                                break;
                            case ItemTypes.HealthPotion:
                                text = "Name: " + item.getName + "\n" +
                                       "Health restored: " + item.getProperty("healthrestored") + "\n" +
                                       "Sell price: " + item.getPrice + "\n" +
                                       "Size: " + item.getSize + "\n" +
                                       "Weight: " + item.getWeight + "\n" +
                                       "Description:\n" + item.getDescription;

                                quickInfoText = "Name: " + item.getName + "\n" +
                                        "Health restored: " + item.getProperty("healthrestored") + "\n" +
                                        "Sell price: " + item.getPrice + "\n" +
                                        "Size: " + item.getSize + "\n" +
                                        "Weight: " + item.getWeight + "\n";
                                Point TextSize = new Point((int)spriteFont.MeasureString(quickInfoText).X, (int)spriteFont.MeasureString(quickInfoText).Y);

                                quickInfoRectangle = new Rectangle(mousePosition.X, mousePosition.Y, TextSize.X, TextSize.Y - 24);

                                if (mousePosition.X + quickInfoRectangle.Width > itemRectangle.Right)
                                    quickInfoRectangle.X = mousePosition.X - quickInfoRectangle.Width;

                                if (mousePosition.Y + quickInfoRectangle.Height > itemRectangle.Bottom)
                                    quickInfoRectangle.Y = mousePosition.Y - quickInfoRectangle.Height;
                                
                                break;
                            default:
                                quickInfoText = string.Empty;
                                break;
                        }

                        

                        if (!Input.IsKeyDown(Global.KeyConfig[5]))
                            textScroll = 0;
                    }
                    else
                    {
                        quickInfoRectangle.Location = mousePosition;

                        if (mousePosition.X + quickInfoRectangle.Width > itemRectangle.Right)
                            quickInfoRectangle.X = mousePosition.X - quickInfoRectangle.Width;

                        if (mousePosition.Y + quickInfoRectangle.Height > itemRectangle.Bottom)
                            quickInfoRectangle.Y = mousePosition.Y - quickInfoRectangle.Height;
                        
                    }
                    lastSelectedItem = item;
                }
            }
            else
            {
                if (!locked)
                {
                    quickInfoRectangle = Rectangle.Empty;
                    quickInfoText = string.Empty;

                    lastSelectedItem = new ItemPresets.EmptySlot();
                }

                if (Input.IsNewMouseOnePress())
                {
                    foreach (Button button in buttons)
                    {
                        if (button.hitbox.Contains(mousePosition))
                            button.Click();
                    }
                }
            }
        }

        /// <summary>
        /// Draws the entire popup
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="graphicsDevice"></param>
        public override void Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
        {
            Random random = new Random();
            spriteBatch.Draw(background, position, Color.White);

            for (int y = 0; y < 8; y++)
                for (int x = 0; x < 16; x++)
                    spriteBatch.Draw(inventoryContents[y + itemScroll][x].getTexture, new Vector2(82 + x * 35 + x * 5, 86 + y * 35 + y * 5), Color.White);

            foreach (PositionedString thisPositionedString in positionedString)
                spriteBatch.DrawString(spriteFont, thisPositionedString.text, thisPositionedString.position, Color.White);

            foreach (Button button in buttons)
                spriteBatch.DrawString(spriteFont, button.text, button.position, Color.White);


            spriteBatch.DrawString(spriteFont, compareText[compareTextIndex], new Vector2(188, 550), Color.White);

            spriteBatch.Draw(white, quickInfoRectangle, new Color(0, 0, 0) * 0.8f);
            spriteBatch.DrawString(spriteFont, quickInfoText, new Vector2(quickInfoRectangle.X, quickInfoRectangle.Y), Color.White);

            spriteBatch.End();

            //Klipp ut allt som är utanför infoText rutan
            graphicsDevice.RasterizerState = new RasterizerState() { ScissorTestEnable = true };
            graphicsDevice.ScissorRectangle = new Rectangle(65, 445, 670, 90);

            spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, graphicsDevice.RasterizerState);

            spriteBatch.DrawString(spriteFont, text, new Vector2(65, 440 + textScroll), Color.White);

            //spritebatch.End();
            //Do not add spriteBatch.end();
        }
    }

    class HUD
    {
        protected Texture2D background;
        protected SpriteFont spriteFont;

        protected Dictionary<Vector2, HUDData> stringData;
        protected Dictionary<Vector2, Texture2D> pictureData;

        /// <summary>
        /// Creates a new HUD without any existing data
        /// </summary>
        public HUD(SpriteFont spriteFont, Texture2D background)
        {
            this.spriteFont = spriteFont;
            this.background = background;

            stringData = new Dictionary<Vector2, HUDData>();
            pictureData = new Dictionary<Vector2, Texture2D>();
        }

        /// <summary>
        /// Creates a new HUD with only stringData
        /// </summary>
        public HUD(SpriteFont spriteFont, Texture2D background, Dictionary<Vector2, HUDData> stringData)
        {
            this.spriteFont = spriteFont;
            this.background = background;

            this.stringData = stringData;
            pictureData = new Dictionary<Vector2, Texture2D>();
        }

        /// <summary>
        /// Creates a new HUD with only pictureData
        /// </summary>
        public HUD(SpriteFont spriteFont, Texture2D background, Dictionary<Vector2, Texture2D> pictureData)
        {
            this.spriteFont = spriteFont;
            this.background = background;

            stringData = new Dictionary<Vector2, HUDData>();
            this.pictureData = pictureData;
        }

        /// <summary>
        /// Creates a new HUD with stringdata and picturedata
        /// </summary>
        public HUD(SpriteFont spriteFont, Texture2D background, Dictionary<Vector2, HUDData> stringData, Dictionary<Vector2, Texture2D> pictureData)
        {
            this.spriteFont = spriteFont;
            this.background = background;

            this.stringData = stringData;
            this.pictureData = pictureData;
        }

        /// <summary>
        /// Sets the value of key to value or adds it if it doesn't already contain it
        /// </summary>
        /// <param name="key">key to look for/add</param>
        /// <param name="value">new value for key</param>
        public void TrySetStringData(Vector2 key, HUDData value)
        {
            if (stringData.ContainsKey(key))
                stringData[key] = value;
            else
                stringData.Add(key, value);
        }

        /// <summary>
        /// Sets an existing value in stringData to value
        /// </summary>
        /// <param name="key">key to look for</param>
        /// <param name="value">new value for keey</param>
        public void SetExistingStringData(Vector2 key, HUDData value)
        {
            stringData[key] = value;
        }

        /// <summary>
        /// Removes an keypairvalue from StringData
        /// </summary>
        /// <param name="key">key to remove</param>
        public void RemoveStringData(Vector2 key)
        {
            stringData.Remove(key);
        }

        /// <summary>
        /// Sets the value of key to value or adds it if it doesn't already contain it
        /// </summary>
        /// <param name="key">key to look for/add</param>
        /// <param name="value">value for key</param>
        public void TrySetPictureData(Vector2 key, Texture2D value)
        {
            if (pictureData.ContainsKey(key))
                pictureData[key] = value;
            else
                pictureData.Add(key, value);
        }

        /// <summary>
        /// Sets an existing value in pictureData to value
        /// </summary>
        /// <param name="key">key to look for</param>
        /// <param name="value">new value for keey</param>
        public void SetExistingPictureData(Vector2 key, Texture2D value)
        {
            pictureData[key] = value;
        }

        /// <summary>
        /// Removes an keypairvalue from PictureData
        /// </summary>
        /// <param name="key">key to remove</param>
        public void RemovePictureData(Vector2 key)
        {
            pictureData.Remove(key);
        }

        /// <summary>
        /// Draws the complete hud
        /// </summary>
        public virtual void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(background, new Vector2(800, 0), Color.White);

            foreach (KeyValuePair<Vector2, HUDData> data in stringData)
            {
                spriteBatch.DrawString(spriteFont, data.Value.prefix + ": " + data.Value.suffix, data.Key, Color.White);
            }

            foreach (KeyValuePair<Vector2, Texture2D> data in pictureData)
            {
                spriteBatch.Draw(data.Value, data.Key, Color.White);
            }
        }
    }
}